import React from 'react'
import { Link } from 'react-router-dom'

import { withFormik, Form, Field, ErrorMessage } from 'formik';

import { Flex, WingBlank, WhiteSpace, Toast } from 'antd-mobile'

import * as Yup from 'yup'

import {API, BASE_URL, setToken} from '../../utils'

import NavHeader from '../../components/NavHeader'

import styles from './index.module.css'

// 转成函数组件的形式
const Login = props => {
  // state = {
  //   username: '',
  //   password: ''
  // }

  // 受控组件的方式拿值，不采用，使用formik接管

  // handleUserName = e => {
  //   this.setState({
  //     username: e.target.value
  //   })
  //   // console.log(this.state.username);
  // }
  // handlePassword(e) {
  //   this.setState({
  //     password: e.target.value
  //   })
  //   // console.log(this.state.password);
  // }

  // handleSubmit = async e => {
  //   e.preventDefault()
  //   const { data: { body, description, status}} = await API.post(`${BASE_URL}/user/login`, {
  //     username: this.state.username,
  //     password: this.state.password
  //   })
  //   if (status === 200) {
  //     // 登录成功
  //     localStorage.setItem('hkzf_token', body.token)
  //     this.props.history.go(-1)
  //   } else if (status === 400) {
  //     // 登录失败
  //     Toast.info(description, 2)
  //   }
  // }
    // console.log(props);
    // Form, Field, ErrorMessage接管后已不需要props
    // const {values, handleSubmit, handleChange, errors, touched, handleBlur} = props
    // 失去焦点时触发handleBlue函数，touched存储了校验结果（true/false）, errors存储了校验错误提示
    return (
      <div className={styles.root}>
        {/* 顶部导航 */}
        <NavHeader className={styles.navHeader}>账号登录</NavHeader>
        <WhiteSpace size="xl" />

        {/* 登录表单 */}
        <WingBlank>
          {/* formik 的Form组件  接管原生form 接管后Form内部处理handleSubmit */}
          {/*  <form onSubmit={handleSubmit}> ---> <Form> */}
          <Form>
            <div className={styles.formItem}>
              {/* formik 的Field组件 接管原生form的input */}
              <Field
                className={styles.input}
                name="username"
                placeholder="请输入账号"
                // formik接管后
                // value={this.state.username} //受控组件方式

                // formik 的Field 接管后已不需要value, onChange, onBlur Field内部处理好了
                // value={values.username}
                // onChange={handleChange}
                // onBlur={handleBlur}
              />
            </div>
            {/* 长度为5到8位，只能出现数字、字母、下划线 */}
            {/* ErrorMessage 组件接管后 无需手动判断是否摸过touched*/}
            {/* {
              touched.username && <div className={styles.error}>{errors.username}</div>
            } */}
            {/* component指定要渲染成的html， name标识字段 */}
            <ErrorMessage className={styles.error} component="div" name="username" />
            <div className={styles.formItem}>
              <Field
                className={styles.input}
                name="password"
                type="password"
                placeholder="请输入密码"
                // 同username
                // value={this.state.password}
                // value={values.password}
                // onChange={handleChange}
                // onBlur={handleBlur}
              />
            </div>
            {/* 长度为5到12位，只能出现数字、字母、下划线 */}
            {/* 同username，由 ErrorMessage组件接管*/}
            {/* {
              touched.password && <div className={styles.error}>{errors.password}</div>
            } */}
            <ErrorMessage className={styles.error} component="div" name="password" />
            <div className={styles.formSubmit}>
              <button className={styles.submit} type="submit">
                登 录
              </button>
            </div>
          </Form>
          <Flex className={styles.backHome}>
            <Flex.Item>
              <Link to="/registe">还没有账号，去注册~</Link>
            </Flex.Item>
          </Flex>
        </WingBlank>
      </div>
    )
  }
// 采用withFromik高阶组件进行表单校验，该高阶组件需要两次调用，第一次传入表单配置项，第二次传入要包装的组件
export default withFormik({
  // mapPropsToValues为表单提供状态（数据）托管组件自己的state
  mapPropsToValues: () => ({ username: '', password: '' }),
  handleSubmit: async (value, {props}) => {
    // 此处的props里仅包含了路由信息
    // console.log('处理表单提交', value, props);
    const { username, password} = value
    // e.preventDefault()
    const { data: { body, description, status } } = await API.post(`${BASE_URL}/user/login`, {
      username,
      password
    })
    if (status === 200) {
      // 登录成功
      // localStorage.setItem('hkzf_token', body.token)
      setToken(body.token)
      // props.history.go(-1)
      const { state } = props.location
      if (!state) {
        props.history.go(-1)
      } else {
        // 从业务逻辑考虑，不应该是props.history.push, push是路由跳转，replace是替换
        // replace会替换浏览器历史记录数组中的最后一项并跳转
        // 例如： /home --> /a 但此时因为没有登入重定向到了/login,当登入成功后业务逻辑上来说点击浏览器返回按钮应该 --> /home
        // 但是pus是跳转到/login replace是跳转到/a  (state.from.pathname为/a)
        // 现有历史记录： ['/home', '/login'] 
        // 如果使用push，结果为： ['/home', '/login', '/a'] 
        // 如果使用replace，结果为： ['/home', '/a'] 
        props.history.replace(state.from.pathname)
      }

    } else if (status === 400) {
      // 登录失败
      Toast.info(description, 2)
    }
  },
  // 表单校验规则
  validationSchema: Yup.object().shape({
    username: Yup.string().required('用户名不能为空').matches(/^[a-zA-Z_\d]{5,8}$/, '长度是5-8位，只能出现数字、字母、下划线'),
    password: Yup.string().required('密码不能为空').matches(/^[a-zA-Z_\d]{5,12}$/,'长度是5-12位，只能出现数字、字母、下划线')
  })
})(Login)
